﻿using Fiddler;
using System;
using System.Drawing;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace GetWechatArticle
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// 52破解论坛有篇关于 Fiddler抓取PC版微信公众所有文章数据的分析，请移步：https://www.52pojie.cn/thread-1646638-1-1.html
        /// </summary>

        /// <summary>
        /// offset为当前获取的第几篇文章，一般不随意修改
        /// </summary>

        //文章列表需要用的一些参数，参数有效期为半小时，过期需要重新获取
        string _biz = "", _uin = "", _key = "", _pass_ticket = "", _appmsg_token = "", _nickname = "";
        /// <summary>
        /// 用于判断上面6个参数是否获取成功，必须全部获取成功才能进行文章列表的读取
        /// </summary>
        bool[] flags = new bool[] { true, true, true, true, true, true, true };
        /// <summary>
        /// 判断6个参数当前获取成功的个数
        /// </summary>
        int paramNum = 0;
        /// <summary>
        /// 默认获取文章的时间间隔
        /// </summary>
        int intervalNum = 20;
        int s = 0;
        /// <summary>
        /// 软件发布及源代码地址
        /// </summary>
        static string BASEURL = "https://www.52pojie.cn/thread-1651719-1-1.html";

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DAL.addText = AddText;
            intervalTxt.Text = intervalNum.ToString();
            LoadText();
            tabControl1.SelectedIndex = 1;
        }

        /// <summary>
        /// 获取所需的参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            _biz = ""; _uin = ""; _key = ""; _pass_ticket = ""; _appmsg_token = ""; _nickname = "";
            flags = new bool[] { true, true, true, true, true, true, true };
            paramNum = 0;
            tabControl1.SelectedIndex = 0;

            InitFiddler();
        }

        /// <summary>
        /// 开始获取文章等操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            GetArticle();
        }

        /// <summary>
        /// 开始获取文章等操作
        /// </summary>
        private void GetArticle()
        {
            try
            {
                //添加公众号信息及对应的表
                DAL.AddUserTable(_biz, nicknameTxt.Text.Trim());
                //获取当前公众号上一次获取文章的时间
                lastdate.Text = DAL.GetLastDate(_biz);

                if (button2.Text.IndexOf("开始") == -1)
                {
                    button1.Enabled = true;
                    button2.Enabled = false;
                    timer2.Enabled = false;
                    timer3.Enabled = false;
                    button2.Text = button2.Text.Replace("停止", "开始");
                }
                else
                {
                    button1.Enabled = false;
                    timer2.Interval = (int.TryParse(intervalTxt.Text.Trim().ToString(), out s) ? s : intervalNum) * 1000;
                    timer2.Enabled = true;
                    button2.Text = button2.Text.Replace("开始", "停止");
                }
            }
            catch (Exception ex)
            {
                button1.Enabled = true;
                button2.Enabled = false;
                timer2.Enabled = false;
                timer3.Enabled = false;
                button2.Text = button2.Text.Replace("停止", "开始");

                AddText("程序错误：" + ex.Message);
            }
        }

        /// <summary>
        /// 获取文章列表时钟
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer2_Tick(object sender, EventArgs e)
        {
            timer2.Enabled = false;
            //当前获取的记录数量，每页10条，数值累加
            string _offset = offsetTxt.Text.Trim();

            string currentUrl = Config.articleListUrl.Replace("{biz}", _biz).Replace("{uin}", _uin).Replace("{key}", _key).Replace("{pass_ticket}", _pass_ticket).Replace("{appmsg_token}", _appmsg_token).Replace("{offset}", _offset);

            string rtn = ProcessListData(currentUrl, _nickname, _biz);
            if (rtn == "ok")//获取列表成功，继续下一页
            {
                timer2.Interval = (int.TryParse(intervalTxt.Text.Trim().ToString(), out s) ? s : intervalNum) * 1000;
                timer2.Enabled = true;

                AddText(rtn);
            }
            else if (rtn.IndexOf("complete") != -1)//获取列表完成，执行文章生成HTML
            {
                DAL.UpdateComplate(_biz);
                AddText(rtn, Color.Blue);

                timer2.Enabled = false;
                timer3.Interval = (int.TryParse(intervalTxt.Text.Trim().ToString(), out s) ? s : intervalNum) * 1000;
                timer3.Enabled = true;
            }
            else if (rtn.IndexOf("no session") != -1)//登录已失效
            {
                AddText(rtn);
                AddText("请重新获取参数后再继续获取文章。", Color.Red);

                timer2.Enabled = false;
                button2.Text = button2.Text.Replace("停止", "开始");
                button2.Enabled = false;
                button1.Enabled = true;
            }
            else if (rtn.IndexOf("error") != -1)//报错
            {
                AddText(rtn, Color.Red);

                timer2.Enabled = false;
                button2.Text = button2.Text.Replace("停止", "开始");
            }
            else
            {
                AddText(rtn, Color.Red);

                timer2.Enabled = false;
                button2.Text = button2.Text.Replace("停止", "开始");
            }
        }

        /// <summary>
        /// 获取文章列表
        /// </summary>
        /// <param name="url">列表url</param>
        /// <param name="_nickname">公众号名</param>
        /// <param name="_biz">公众号编号</param>
        /// <returns></returns>
        private string ProcessListData(string url, string _nickname, string _biz)
        {
            string rtnStr = "";
            try
            {
                string res = OP.GetUrlContent(url);

                if (res.IndexOf("\"errmsg\":\"ok\"") != -1)
                {
                    rtnStr = "ok";
                    res = res.Replace("\\\"", "\"").Replace("\"{", "{").Replace("}\"", "}").Replace("\\/", "/");

                    string _next_offset = OP.RegExpFindOne(Config.offsetPat, res);
                    string _msgCount = OP.RegExpFindOne(Config.msgcountPat, res);
                    if (OP.RegIsMatch(Config.intPat, _msgCount))
                    {
                        DAL.AnalyzeData(_biz, res);

                        string lastdates = OP.GetListLastDate(res);
                        if (!OP.RegIsMatch(Config.datetimeIntPat, lastdates))
                        {
                            rtnStr = "error: 获取列表最后时间错误";
                        }
                        else
                        {
                            long dataLastDate = OP.ConvertDateTimeToInt(DateTime.Parse(lastdate.Text.Trim()), 2);
                            long listLastDate = long.Parse(lastdates);
                            if (dataLastDate - listLastDate > 3 * 24 * 3600)//当前列表最后文章发布时间比库里存的时候早3天，则停止表示全部获取完成
                            {
                                rtnStr = "complete: 已达到上次获取位置，文章列表获取完成，转入生成文章HTML。";
                            }
                            else
                            {
                                if (OP.RegIsMatch(Config.intPat, _next_offset))
                                {
                                    offsetTxt.Text = _next_offset;
                                }
                                else
                                {
                                    rtnStr = "error: next_offset error";
                                }
                            }
                        }
                    }
                    else
                    {
                        rtnStr = "complete: 列表获取完成，转入生成文章HTML。";
                    }
                }
                else if (res.IndexOf("\"errmsg\":\"no session\"") != -1)
                {
                    rtnStr = "error: no session";
                }
                else
                {
                    rtnStr = "error: other error。" + res;
                }
            }
            catch (Exception ex)
            {
                rtnStr = "error[程序1]: " + ex.Message;
            }
            return rtnStr;
        }

        /// <summary>
        /// 生成HTML文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer3_Tick(object sender, EventArgs e)
        {
            bool timer3Flag = false;
            int status = 10;//1-2为生成错误，3为多次重试还是错误，9为被禁文章，10为已经生成HTML
            int id = 0;
            timer3.Enabled = false;

            string rtn = ProcessInfoData(ref id);

            if (rtn.IndexOf("success:") != -1)//生成HTML文件成功，继续下一篇
            {
                AddText(rtn);
                status = 10;

                timer3Flag = true;
            }
            else if (rtn.IndexOf("complete:") != -1)//生成HTML完成，停止
            {
                AddText(rtn, Color.Blue);
                timer3Flag = false;
            }
            else if (rtn.IndexOf("error:") != -1)//报错
            {
                AddText(rtn, Color.Red);
                status = 1;

                timer3Flag = true;
            }
            else if (rtn.IndexOf("violate:") != -1)//文章被禁或删除
            {
                AddText(rtn, Color.Red);
                status = 9;

                timer3Flag = true;
            }
            else
            {
                status = 1;

                timer3Flag = true;
            }

            timer3.Interval = (int.TryParse(intervalTxt.Text.Trim().ToString(), out s) ? s : intervalNum) * 1000;
            timer3.Enabled = timer3Flag;

            try
            {
                if (timer3Flag)
                {
                    DAL.SetArticleStatus(_biz, id, status);
                }
                else
                {
                    GetArticle();
                }
            }
            catch (Exception ex)
            {
                AddText("error[程序3]: " + ex.Message, Color.Red);
            }
        }

        /// <summary>
        /// 获取公众号文章内容，并生成HTML文件
        /// </summary>
        /// <returns></returns>
        private string ProcessInfoData(ref int id)
        {
            string rtn = "";
            id = 0;

            try
            {
                Article art = DAL.GetArticleUrl(_biz);
                if (art.rtnFlag)
                {
                    if (art.rtnStr == "没有记录")
                    {
                        rtn = "complete: 所有文章都已完成写入HTML文件。";
                    }
                    else
                    {
                        id = art.id;
                        string _nickname = nicknameTxt.Text.Trim();
                        int _type = art.type;

                        if (_type == 1)//链接文章
                        {
                            string contentHtml = OP.GetUrlContent(art.url);
                            if (contentHtml.Length > 100 && contentHtml.IndexOf("title") != -1)
                            {
                                if ((contentHtml.IndexOf("del_reason: '") != -1 && contentHtml.IndexOf("del_reason_id: '") != -1) || contentHtml.IndexOf("<div class=\"weui-msg__title warn\">此内容") != -1 || contentHtml.IndexOf("<div class=\"weui-msg__title warn\">该内容") != -1)
                                {
                                    string reason = OP.RegExpFindOne(Config.reasonPat, contentHtml);
                                    if (reason.Length == 0)
                                        reason = OP.RegExpFindOne(Config.reasonPat2, contentHtml);
                                    string title = Regex.Replace(Regex.Replace(Regex.Replace(art.title, "\r", ""), "\n", ""), @"\s", " ");
                                    rtn = "violate: 被禁文章:" + art.title + "(" + art.url + ")，原因：" + reason;
                                }
                                else
                                {
                                    string time = OP.RegExpFindOne(Config.timePat, contentHtml);
                                    if (time.Length < 10)
                                        time = OP.RegExpFindLastOne(Config.timePat2, contentHtml);
                                    if (time.Length < 10)
                                        time = OP.RegExpFindLastOne(Config.timePat3, contentHtml);
                                    if (time.Length < 10)
                                        time = OP.RegExpFindLastOne(Config.timePat4, contentHtml);
                                    if (time.Length < 10)
                                        time = OP.RegExpFindOne(Config.timePat5, contentHtml);
                                    //if (time.Length < 10)
                                    //    time = OP.RegExpFindOne(Config.timePat6, contentHtml);
                                    if (time.Length >= 10)
                                        time = time.Substring(0, 10);
                                    else
                                    {
                                        rtn = "error: " + art.title + "(" + art.url + ")" + "，原因：日期格式错误，" + time;
                                    }
                                    if (OP.RegIsMatch(Config.datetimeIntPat, time))
                                        time = OP.ConvertIntToDateTime10(double.Parse(time)).ToString("yyyy-MM-dd");
                                    string title = OP.RegExpFindOne(Config.titlePat, contentHtml);
                                    if (title.Length == 0)
                                        title = OP.RegExpFindOne(Config.titlePat2, contentHtml);
                                    title = Regex.Replace(Regex.Replace(Regex.Replace(title, "\r", ""), "\n", ""), @"\s", " ");
                                    //去除一些多余且不能用于文件名的字符
                                    title = Regex.Replace(title, Config.titleRepPat, "");
                                    //处理图片链接
                                    contentHtml = Regex.Replace(contentHtml, "data-src", "src");
                                    contentHtml = Regex.Replace(contentHtml, "visibility: hidden", "");

                                    OP.CreateHtml(time + " " + title, _nickname, contentHtml);
                                    rtn = "success: " + art.title + "(" + art.url + ")" + "，获取文章成功。";
                                }
                            }
                            else
                            {
                                rtn = "error: 获取文章内容失败，" + art.url;
                            }
                        }
                        else//内容文章
                        {
                            string contentHtml = art.contents;
                            string title = Regex.Replace(contentHtml, Config.titleRepPat, "");
                            title = contentHtml.Substring(0, (contentHtml.Length > 20) ? 20 : contentHtml.Length);
                            string time = Convert.ToDateTime(art.times).ToString("yyyy-MM-dd");
                            OP.CreateHtml(time + " " + title, _nickname, contentHtml);
                            rtn = "success: " + title + "(纯内容文章)" + "，获取文章成功。";
                        }
                    }
                }
                else
                {
                    rtn = "error: " + art.rtnStr;
                }
            }
            catch (Exception ex)
            {
                rtn = "error[程序2]: " + ex.Message;
            }

            return rtn;
        }

        #region Fiddler设置
        //https代理
        Proxy oSecureEndpoint;
        //伪装https服务器
        int iSecureEndpointPort = 8877;
        //代理端口
        int iStartPort = 8888;

        /// <summary>
        /// 初始化Fiddler
        /// </summary>
        private void InitFiddler()
        {
            if (button1.Text.IndexOf("获取参数") != -1)
            {
                button1.Text = "①停止获取";
                nicknameTxt.Enabled = true;

                //恢复代理
                if (FiddlerApplication.oProxy != null && !FiddlerApplication.oProxy.IsAttached)
                {
                    FiddlerApplication.oProxy.Attach();
                    oSecureEndpoint.Attach();
                }
                else//创建代理
                {
                    //这个名字随便
                    FiddlerApplication.SetAppDisplayName("Fiddler");
                    //绑定事件处理————当会话结束之后
                    FiddlerApplication.AfterSessionComplete += On_AfterSessionComplete;

                    //-----------处理证书-----------
                    //伪造的证书
                    X509Certificate2 oRootCert;
                    //获取本地证书库中保存过伪造的证书
                    oRootCert = CertMaker.GetRootCertificate();
                    //如果没有伪造过证书并把伪造的证书加入本机证书库中
                    if (null == oRootCert)
                    {
                        //创建伪造证书
                        CertMaker.createRootCert();

                        //重新获取
                        oRootCert = CertMaker.GetRootCertificate();

                        //打开本地证书库
                        X509Store certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
                        certStore.Open(OpenFlags.ReadWrite);
                        try
                        {
                            //将伪造的证书加入到本地的证书库
                            certStore.Add(oRootCert);
                        }
                        finally
                        {
                            certStore.Close();
                        }
                    }

                    //指定伪造证书
                    FiddlerApplication.oDefaultClientCertificate = oRootCert;
                    //忽略服务器证书错误
                    CONFIG.IgnoreServerCertErrors = true;
                    //信任证书
                    CertMaker.trustRootCert();
                    //
                    FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);
                    //启动代理服务
                    FiddlerApplication.Startup(iStartPort, FiddlerCoreStartupFlags.DecryptSSL | FiddlerCoreStartupFlags.AllowRemoteClients | FiddlerCoreStartupFlags.Default);
                    //创建https代理
                    oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, oRootCert);
                }
            }
            else
            {
                if (FiddlerApplication.oProxy.IsAttached)
                {
                    FiddlerApplication.oProxy.Detach();
                    oSecureEndpoint.Detach();
                }
                button1.Text = "①获取参数";
                nicknameTxt.Enabled = false;
            }
        }

        private void On_AfterSessionComplete(Session oS)
        {
            string url = oS.fullUrl.Trim();
            if (url.IndexOf("mp.weixin.qq.com") != -1)
            {
                if (oS.bHasResponse)
                {
                    Invoke(new Action(() =>
                    {
                        //获取_biz
                        if (_biz.Length == 0)
                        {
                            _biz = OP.RegExpFindOne(Config.bizPat, url);
                            if (_biz.Length > 0 && flags[0])
                            {
                                flags[0] = false;
                                AddText($"_biz:{_biz}");
                                paramNum++;
                            }
                        }

                        //获取_uin
                        if (_uin.Length == 0)
                        {
                            _uin = OP.RegExpFindOne(Config.uinPat, url);
                            if (_uin.Length > 0 && flags[1])
                            {
                                flags[1] = false;
                                AddText($"_uin:{_uin}");
                                paramNum++;
                            }
                        }

                        //获取_key
                        if (_key.Length == 0)
                        {
                            _key = OP.RegExpFindOne(Config.keyPat, url);
                            if (_key.Length > 0 && flags[2])
                            {
                                flags[2] = false;
                                AddText($"_key:{_key}");
                                paramNum++;
                            }
                        }

                        //获取_appmsg_token
                        if (_appmsg_token.Length == 0)
                        {
                            _appmsg_token = OP.RegExpFindOne(Config.appmsg_tokenPat, url);
                            if (_appmsg_token.Length > 0 && flags[3])
                            {
                                flags[3] = false;
                                AddText($"_appmsg_token:{_appmsg_token}");
                                paramNum++;
                            }
                        }

                        //获取_pass_ticket
                        if (_pass_ticket.Length == 0)
                        {
                            _pass_ticket = OP.RegExpFindOne(Config.pass_ticketPat, url);
                            if (_pass_ticket.Length > 0 && flags[4])
                            {
                                flags[4] = false;
                                AddText($"_pass_ticket:{_pass_ticket}");
                                paramNum++;
                            }
                        }

                        //获取_nickname
                        if (url.IndexOf("s?__biz=") != -1)
                        {
                            string body = oS.GetResponseBodyAsString();
                            _nickname = OP.RegExpFindOne(Config.nicknamePat, body);
                            if (_nickname.Length > 0 && flags[5])
                            {
                                flags[5] = false;
                                AddText($"_nickname:{_nickname}");
                                string _oldnickname = nicknameTxt.Text;
                                nicknameTxt.Text = _nickname;
                                //如果本次获取的公众号与上一次为同一个，则不修改offset，表示这次从第offset个文章开始，接着进行获取后面的文章
                                //如果为不同，则把offset修改为0，表示第一篇文章开始获取
                                if (_oldnickname != _nickname)
                                {
                                    offsetTxt.Text = "0";
                                }
                                paramNum++;
                            }
                        }

                        if (paramNum == 6 && flags[6])
                        {
                            flags[6] = false;
                            SetProxyStatus();
                            AddText("参数获取成功，可进行文章获取。", Color.Blue);
                            button2.Enabled = true;
                            GetArticle();
                        }

                    }));
                }
            }
        }



        /// <summary>
        /// 设置Fiddler代理为暂停
        /// </summary>
        public void SetProxyStatus()
        {
            if (button1.Text.IndexOf("停止获取") != -1)
            {
                if (FiddlerApplication.oProxy.IsAttached)
                {
                    FiddlerApplication.oProxy.Detach();
                    oSecureEndpoint.Detach();
                }
                button1.Text = "①获取参数";
                nicknameTxt.Enabled = false;
            }
        }

        #endregion

        #region
        public void AddText(string text, Color color)
        {
            this.Invoke(new ThreadStart(delegate
            {
                if (text.Length > 0)
                {
                    richTextBox1.SelectionColor = color;
                    richTextBox1.AppendText(text + " " + DateTime.Now.ToString() + "\r\n");

                    richTextBox1.SelectionStart = richTextBox1.Text.Length;
                    richTextBox1.SelectionLength = 0;
                    richTextBox1.Focus();
                    richTextBox1.SelectionColor = Color.Black;
                }
            }
            ));
        }

        public void AddText(string text)
        {
            AddText(text, Color.Black);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(BASEURL);
        }

        public void LoadText()
        {
            this.Invoke(new ThreadStart(delegate
            {
                richTextBox2.Clear();
                Font f = this.richTextBox2.Font;
                Font fontB = new Font(f, FontStyle.Bold);
                Font fontR = new Font(f, FontStyle.Regular);
                Font fontS = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Bold);

                richTextBox2.SelectionColor = Color.Blue;
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("使用方法：\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("1、先关掉所有正在打开的公众号文章。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("2、点击");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【①获取参数】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("，然后再打开需要下载文章的公众号，选择打开公众号里任意一文章。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("3、文章加载完全后，");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【运行日志】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("里会显示获取的各项参数。当参数获取完成后，会自动开始获取文章。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("4、请不要");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("多开");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("本软件。");
                richTextBox2.AppendText("\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.Blue;
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("获取一个公众号里文章的流程：\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("先获取必须的参数-->获取公众号的所有文章并入SQLITE数据库里-->再从数据库里取出文章，一篇一篇下载并做标记。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.Blue;
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("获取内容：\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("只是把文章的内容保存，没有做处理。图片使用的是网络地址，没有保存留言，可以自己修改添加上去。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.Red;
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("会产生的问题及解决方法：\r\n");
                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("1、当正在获取参数的时候，浏览器可能会出现：");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【未连接：有潜在的安全问题】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("，而不能浏览网页。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：大概原因是Fiddler的证书问题，只需要等参数获取完成或手动停止参数获取即可恢复。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("2、当没有关闭现有打开的公众号文章时，此时点击");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【获取参数】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("有可能会获取到当前浏览文章的参数，当你要获取另外一个公众号的数据时，可能会出现参数错误的情况。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：先关掉所有正在浏览的公众号文章，然后再点击");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【①获取参数】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("，再打开需要下载的公众号的任意一文章。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("3、出现提示error类的信息问题。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：一般按照方法重试一/几次就可以。如果不行，可关掉软件重新打开。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("4、在获取参数时，软件意外关闭或是主动关闭，再访问网页时会提示：");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【代理服务器拒绝连接】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：这是由于在获取参数时，软件会修改系统的代理，如果没有停止，该代理会一直存在。只需要重开软件，点击");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【①获取参数】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("，然后再点击");
                richTextBox2.SelectionFont = fontB;
                richTextBox2.AppendText("【①停止获取】");
                richTextBox2.SelectionFont = fontR;
                richTextBox2.AppendText("即可。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("5、正在获取文章时，软件意外或主动关闭后，重新打开后，以前文章是否会重复获取或下载。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("答：不会重复，在获取文章列表时关闭，下次重开后，还是会重第一篇文章开始获取，找到重复的会自动跳过。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("      当在下载文章时关闭，下次重开后，会从下一篇未下载的文章开始下载。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("6、由于Fiddler证书安装问题，可能会出现其它未知错误，请使用搜索引擎查找相关解决方法，或提供可复现的方案进行回帖。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("7、有时候会出现打开文章后，参数没有获取完全，一直不进行采集。\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：关掉文章后再打开一次一篇文章即可，尽量不使用刷新，有些参数只有第一次打开才有。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("8、软件被WIN10的安全中心删除了怎么办？\r\n");
                richTextBox2.SelectionColor = Color.Maroon;
                richTextBox2.AppendText("解决方法：通过安全中心，添加到排除列表里面。\r\n");
                richTextBox2.AppendText("\r\n");

                richTextBox2.AppendText("\r\n");

                richTextBox2.SelectionColor = Color.Red;
                richTextBox2.SelectionFont = fontS;
                richTextBox2.AppendText("免责和隐私声明：\r\n");
                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("1、本软件只用于个人技术学习和免费使用，请勿用于非法用途，如产生法律纠纷与本人和52破解论坛无关。\r\n");
                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("2、本软件在任何情况下都不会收集个人隐私及其它任意数据。\r\n");
                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("3、本软件为开源软件，如经过修改，发生任何意外情况均与本人和52破解论坛无关。\r\n");
                richTextBox2.SelectionColor = Color.DarkBlue;
                richTextBox2.AppendText("4、软件发布地址及源代码获取地址，"+BASEURL+"。\r\n");

                richTextBox2.Select(0, 0);

            }
            ));
        }
        #endregion

    }
}
